﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using GameViewer.Core.Controls;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;

namespace GameViewer.Core.Viewers
{
    public class MeshViewer : Viewer
    {
        protected Vector3 mCameraPosition = new Vector3(0.0f, 0.0f, 100.0f);
        protected Vector3 mCameraLookAt = new Vector3(0.0f, 0.0f, 0.0f);
        protected Matrix mCameraProjectionMatrix;
        protected Matrix mCameraViewMatrix;
        protected Matrix mWorld;
        protected GraphicsDevice mDevice;
        protected bool mReady = false;
        private List<ViewerComponent> mViewerComponents;

        #region component

        private GameViewer.Core.Controls.RenderControl renderControl1;

        private void InitializeComponent()
        {
            this.renderControl1 = new GameViewer.Core.Controls.RenderControl();
            this.SuspendLayout();
            // 
            // renderControl1
            // 
            this.renderControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.renderControl1.Location = new System.Drawing.Point(0, 0);
            this.renderControl1.Name = "renderControl1";
            this.renderControl1.Size = new System.Drawing.Size(284, 262);
            this.renderControl1.TabIndex = 0;
            this.renderControl1.Text = "renderControl1";
            // 
            // MeshViewer
            // 
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.renderControl1);
            this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.Name = "MeshViewer";
            this.ResumeLayout(false);

        }

        #endregion

        public MeshViewer()
        {
            this.InitializeComponent();
            this.InitializeEvent();

            mViewerComponents = new List<ViewerComponent>();
            mViewerComponents.Add(new Input(this));
        }

        private void InitializeEvent()
        {
            this.renderControl1.DeviceReady += new EventHandler(renderControl1_DeviceReady);
        }

        void renderControl1_DeviceReady(object sender, EventArgs e)
        {
            mReady = true;
            mDevice = this.renderControl1.GraphicsDevice;
            this.renderControl1.DeviceUpdated -= renderControl1_DeviceUpdated;
            this.renderControl1.DeviceUpdated += new EventHandler(renderControl1_DeviceUpdated);
            this.renderControl1.PrepareRendering();
            //IServiceProvider service =(IGraphicsDeviceService) this.renderControl1.Services.GetService(typeof(IGraphicsDeviceService));
            this.Initialize();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Icon = IconManager.Instance.GetIcon("globe");
            this.Text = "mesh";
        }

        void renderControl1_DeviceUpdated(object sender, EventArgs e)
        {
            foreach (ViewerComponent vc in mViewerComponents)
            {
                vc.Update(this, this.Timer);
            }
            this.DrawModel();
        }

        protected virtual void Initialize()
        {
            mCameraViewMatrix = Matrix.CreateLookAt(
                mCameraPosition,
                mCameraLookAt,
                Vector3.Up);

            mCameraProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45.0f),
                this.renderControl1.GraphicsDevice.Viewport.AspectRatio,
                1.0f,
                10000.0f);

            mWorld = Matrix.CreateFromYawPitchRoll(1, 1, 1);        
        }

        protected virtual void DrawModel()
        {            
        }

        public new Color BackColor
        {
            get
            {
                return this.renderControl1.BackColor;
            }
            set
            {
                this.renderControl1.BackColor = value;
            }
        }

        public Stopwatch Timer
        {
            get
            {
                return renderControl1.Timer;
            }
        }

        public ServiceContainer Services
        {
            get
            {
                return this.renderControl1.Services;
            }
        }

        public Vector3 CameraPosition
        {
            get
            {
                return mCameraPosition;
            }
            set
            {
                mCameraPosition = value;
            }
        }

        public Vector3 CameraLookAt
        {
            get
            {
                return mCameraLookAt;
            }
            set
            {
                mCameraLookAt = value;
            }
        }

        public Matrix CameraProjectionMatrix
        {
            get
            {
                return mCameraProjectionMatrix;
            }
            set
            {
                mCameraProjectionMatrix = value;
            }
        }

        public Matrix CameraViewMatrix
        {
            get
            {
                return mCameraViewMatrix;
            }
            set
            {
                mCameraViewMatrix = value;
            }
        }

        public Matrix World
        {
            get
            {
                return mWorld;
            }
            set
            {
                mWorld = value;
            }
        }

        public GraphicsDevice Device
        {
            get
            {
                return mDevice;
            }
            set
            {
                mDevice = value;
            }
        }                
    }
}
